#pragma once

#include <iostream>
#include <vector>
#include <string>
#include <functional>
#include <pthread.h>
#include <unistd.h>
#include <cstdio>

namespace threadModel
{
    //下面两句代码相同意思
    // using func_t = std::function<void()>;
    // typedef std::function<void()> func_t;

    // typedef void(*func_t)(threadData *td);
    // typedef std::function<void()> func_t;
    // 包装器包装函数时只针对类型进行包装
    using func_t = std::function<void(const std::string& )>;

    class mythread
    {
    public:
        void execute()
        {
            std::cout << _name << " is running" << std::endl;
            _isrunning = true;
            _func(_name);
            _isrunning = false;
        }

    public:
        mythread(const std::string &name, func_t func)
            :_name(name)
            ,_func(func)
        {
            std::cout << "create " << name << " done" << std::endl;
        }

        // 给一个函数加上static，修饰成静态函数之后，
        // 该函数是属于类的，但是不可以使用类内部的  私有成员变量
        // 但是该函数的参数不再拥有this指针
        static void *threadRoute(void *args)
        {
            mythread* self = static_cast<mythread*>(args);
            self->execute();
            return nullptr;
        }

        bool start()
        {
            // 裸的 :: 强调的是不要用当前命名空间中的方法，而是直接使用pthread.h中的方法
            int n = ::pthread_create(&_tid, nullptr, threadRoute, this);
            if (n != 0)
            {
                return false;
            }
            return true;            
        }
        
        std::string status()
        {
            if (_isrunning)
            {
                return "running";
            }
            else
            {
                return "sleep";
            }
        }

        void stop()
        {
            if (_isrunning)
            {
                ::pthread_cancel(_tid);
                _isrunning = false;
                std::cout << _name << " stop" << std::endl;
            }
        }

        void join()
        {
            ::pthread_join(_tid, nullptr);
            std::cout << _name << " joined" << std::endl;
        }

        std::string name()
        {
            return _name;
        }
        
        ~mythread()
        {
            //可以写下如下两句话，但是没必要
            // stop();
            // join();
        }

    private:
        std::string _name;
        pthread_t _tid;
        bool _isrunning;
        func_t _func; // 线程要执行的回调函数
    };
}